I finally figured this out. The solution has two parts. First, setup.py needs to use extra_link_args to tell the linker to add a correct rpath to the compiled module:
if platform.system() == 'Darwin':
extra_link_args.append('-Wl,-rpath,'+lib_path)
where lib_path is the directory where the libraries are installed. Second, all of the libraries you're linking against must have install names that begin with "@rpath/". For example, if a library is called "libFoo.dylib", its install name should be "@rpath/libFoo.dylib". You can use "install_name_tool -id" to change the install name of a library.