As you have discovered, you can't return from KillLayer() inside its each() loop because a return statement in that context has a different meaning.
Here's a couple of different approaches :
1: Use a boolean flag to signal whether or not a deletion took place and treat the Deferred accordingly.
function KillLayer(id) {
    var defer = $.Deferred(), deleted = false;
    $.each(vm.get("DeviceData"), function (idx, item) {
        if (item.Type == id) {
            vm.DeviceData.splice(idx, 1); // remove the item from the list
            removeLayer(defer, id);  // delete it from the PouchDB (IDB) database (async)
            deleted = true;
            return false;//break from each() loop
        }
    });
    return deleted ? defer.promise() : defer().resolve().promise();//return either a promise of deletion or a ready-resolved promise.
}
2: (If you have control over removeLayer()) Arrange for removeLayer() to generate and return its own promise, rather than passing in a Deferred. This will allow you to simplify KillLayer() as follows:
function KillLayer(id) {
    var deletionPromise;
    $.each(vm.get("DeviceData"), function (idx, item) {
        if (item.Type == id) {
            vm.DeviceData.splice(idx, 1); // remove the item from the list
            deletionPromise = removeLayer(id);  // delete it from the PouchDB (IDB) database (async), and receive back a promise
            return false;//break from each() loop
        }
    });
    return deletionPromise || $.Deferred().resolve().promise(); //return either a promise of deletion from the DB, or a ready-resolved promise
}
Although there's only one line difference, I would contend that the second appraoch is cleaner. As removeLayer() performs an asynchronous activity, it should really return a promise of its own, and not rely on a Deferred being passed to it.