The normal rule would be that if you can take a reference then you do. With the case of f3 in your example though, the fact it deletes the pointer suggests it is much simpler if your function takes a pointer, as nobody would expect a function to delete a reference.
f2 forces the user to pass in a non-NULL so a reference is a good idea. Presumably const-correct without any further information, i.e. f2 may modify the Obj by calling a non-const method on it.
It is difficult to see whether the design is a good one with names like f1, f2 and f3. Sometimes the names can make all the difference. For example, if the name of f3 is "useAndDispose" or similar it is clear to the caller of the function that the pointer will get deleted after use.
Similarly if your function returns a resource that the user must clean-up, a name that indicates this (createSomething rather than getSomething) is usually preferable.
Daniel said "typically" you do not delete pointers passed to you. Not "never" though. The function may specifically be a clean-up function or it could be a workflow situation whereby something is passed around and then disposed of.
I would say though that you should never delete references passed to you (taking their address first, of course) because nobody looking at your code would ever expect it to do that.