how to keep my retain counts as low as possible
I don't understand this. What makes you think you need to worry about retain counts at all? The retain count is an implementation detail, forget about it. All you need to worry about is whether you own an object.
I can't wrap my head around whether to retain (using retain properties, usually) or just assign instance variables.
In almost all cases you want to retain or copy when you assign instance variables. The main exception is retain cycles. Sometimes, you find yourself in a situation where object A has a reference to object B and object B has a reference to object A. If A retained B and B retained A, you cannot rely on the normal pattern of releasing references in dealloc to make them go away. In this situation, it is usual to nominate one object as the owner and the other as the owned. The owned object would then not retain its reference to the owner.
An example of this would be a tree structure where the parent node has references to its children and each child has a reference to its parent. If each child retained its parent, when the application is done with the parent, it won't go away, because it has been retained by all its children. So the parent reference is implemented as a weak reference which means that the child does not retain its parent.
It's a very common pattern with delegates for the owner of an object to set itself as the object's delegate. For example, the controller of a table view is often also the table view's data source and/or delegate. If the table view retained the delegate you would have a retain cycle (since the controller has already retained the view). This is why the convention "delegates aren't retained" has arisen.
You should definitely copy if the object you want a reference to implements NSCopying and you need it not to change while you have ownership. An example from Cocoa is the keys of elements in an NSDictionary. If the keys were to change while in the dictionary, it would be a disaster. So NSDictionary copies its keys.
I know that the risk is that the retain count goes down to zero and I am left holding the bag (or left holding many extra bags and memory), but... how should I organize my application so that this doesn't happen?
Simple: follow the Cocoa memory management rules. If something goes away while you are holding a reference to it, you did not own that something. If you need something to hang around for longer than the scope of the current method, you should retain it.