I don't really agree with the answer marked as correct.
NOT IN can only be used in limited cases. The comparison condition must be single-column, and there must not be any null values in the comparison column in the subquery. Because of those limitations, I never use NOT IN for this kind of questions - I prefer to use the same method in all cases.
NOT EXISTS and the outer join with IS NULL test can both be used under all circumstances, but I far prefer the NOT EXISTS method, because it is far easier to write, and (even more important!) to understand when you have to revisit your code later. In most cases, the execution plan will be the same, so there is no performance benefit of one over the other (this was not always true in older versions of SQL Server, but that has long been changed).
So the technically correct answer to the question would be that only NOT EXISTS and outer join with IS NULL test (a so called anti-semi-join) can always be used. And I would add that I recommend sticking to the NOT EXISTS method for maintainability, unless you happen to run into a situation where the execution plans are not equal, and the plan with the anti-semi-join performs better - and even in that case, I would still prefer the NOT EXISTS version, unless the performance difference prevents me from achieving the required response times.
P.S. The article by Pinal Dave that is referenced only compares anti-semi-join with NOT IN, not with NOT EXISTS; they are not always equivalent (when NULL values can be involved). And he then bases his conclusions on the percentages in the execution plan output; these are estimated costs, not actual costs, and they can be very wrong - so this is one of the worst methods for determining if a query is faster or not.
EDIT: Corrected an embarassing typo