I'll give a shot at answering this based on my own understanding, though please chime in if I have this wrong in some way...
Push and PopAssetDependencies let you control which asset bundles are dependent on another (ie which assets can be excluded). When you call PushAssetDependencies, it instructs BuildPipeline to exclude assets in the next bundle it builds that were already included in the previous one. Dependent asset bundles have to be built in order and then loaded in order. For PushAssetDependencies to work you have to build all of your asset bundles in one script as there's no way (as far as I know) to build an asset bundle with dependencies to a pre-existing bundle.
Here's an example. Suppose you want to create 2 bundles (Bundle1 and Bundle2) and you want Bundle2 to reference assets in Bundle1, instead of including them twice separately. For the sake of visualization, let's say that there's a huge texture file "humungous.png" used by both bundles, but you really only need to have it included in Bundle1. Here's how you would build the bundles with an editor script:
var mode : int = BuildAssetBundleOptions.CollectDependencies |
BuildAssetBundleOptions.CompleteAssets |
BuildAssetBundleOptions.DeterministicAssetBundle;
var path : String = Application.dataPath+"/Bundle1.assetbundle";
BuildPipeline.PushAssetDependencies();
BuildPipeline.BuildAssetBundle(AssetDatabase.LoadMainAssetAtPath("Assets/Prefabs/myObject1.prefab"), null, path, mode, BuildTarget.iPhone);
path = Application.dataPath+"/Bundle2.assetbundle";
BuildPipeline.PushAssetDependencies();
BuildPipeline.BuildAssetBundle(AssetDatabase.LoadMainAssetAtPath("Assets/Prefabs/myObject2.prefab"), null, path, mode, BuildTarget.iPhone);
BuildPipeline.PopAssetDependencies();
BuildPipeline.PopAssetDependencies();
Because PushAssetDependencies was called before building Bundle2, the "humungous.png" file would be in Bundle1, and Bundle2 would only store a reference to it.
Even if you don't need to redistribute Bundle1, it needs to be rebuilt in the script to correctly prepare Bundle2's dependencies. Each call to PushAssetDependencies tells the BuildPipeline to exclude the shared dependencies of the previous asset bundle in the one created next. While PopAssetDependencies removes the exclusion. The Push and Pop commands are hierarchical, meaning you can nest dependencies. For example, consider if you had a complex project with a bundle for base assets, then other sets of bundles of shared assets for specific environments. Using Push and Pop you can create 'layers' of dependencies.
The use of DeterministicAssetBundle means that each time asset bundles are created, the same internal IDs for objects will be used. This ensures that when you build bundles, the assets are referenced the same way every time. If you don't use DeterministicAssetBundle, then there's a risk that there will be conflicts with new bundles and previously distributed bundles.
Hopefully that helps some.