Well your loop is equivalent to:
return db.Observations.Where(o => !Observations.Any(oo => oo.Id == o.Id));
but that's no more efficient that what you have.
A more efficient method would be to create a HashSet of IDs and filter off of that:
HashSet<int> ids = new HashSet<int>(Observations.Select(o => o.Id));
return db.Observations.Where(o => !ids.Contains(o.Id));
That way you're only traversing the main list once in order to create a HashSet
that can be searched in O(1) time.