Branching and merging in TFS provide a more robust way to accomplish what sharing and pinning are often used for in VSS.  In TFS, you would branch a directory (source), using the "branch source target" command, to the desired location (target).  Then when there are changes in the source that you need in the target, you would use the "merge source target" command to propagate the changes.  The merge command remembers what changes have have been brought over to the target, so it brings the target up to date with the source by only merging changes that have not been merged.

The merge command will pend edits, branches for files added, deletes, etc. in the target (in TFS, commands pend changes and then the checkin command submits all changes in a single atomic operation).  After running the merge, command you would then build the software and test it.  Additional changes may need to be made in the target, such as when you change a function or method signature.  When everything is ready, you would check in the merged changes, along with any other changes you needed to make, in a single atomic operation.

By doing this, you are able to build and verify before checkin each branch when it merges in the changes from the source.

There is no penalty in TFS with respect to having multiple branches of the same file.  In the SQL database, they all reference the same content.  Only when a branched file changes does new content get added.

With respect to merging binary files, there is nothing to do except run merge followed by checkin if the binary files in the target do not change.  If binary files in the target have changed, the merge command will produce conflicts for those files, and you would have to pick which to keep (source or target -- there is no 3-way content merge option, of course) when resolving the conflict.

If you want to have every project always use the same same file and immediately see new versions as soon as they are checked in, putting the file in a common location in the TFS repository, such as $/public/bin/dlls, is the way to go.  That does mean that everything that references it should use relative paths.  And since there is no isolation, everything that depends on the file must be checked prior to checkin, or you run the risk of silently breaking other projects (i.e., it requires manual coordination).