Arduino is meant to be easy way for non-technical people and so it hides as much as it can from plain view to be simple.
For simple project it works at the cost of overhead of copying libraries here and there and using Arduino's "IDE". Calling programs "sketches" and manipulate it to hide, that it is in C++. And so on and so on.
If you want to make more complicated projects, version control, good environment and such, you need to leave "simply Arduino way" and start using more powerful and complicated tools.
I personally use
https://github.com/sudar/Arduino-Makefile
https://github.com/ladislas/Bare-Arduino-Project
and have it in GIT repositories.
This way I can share libraries between projects in group, also links to libraries outside the tree works, as well as gits submodules, both allowing you to have updated libraries from 3rd party aviable to all projects, also those old ones.
I still use a lot of Arduino (like setup/loop, digitalRead and such), but also I use "normal" g++ constructs on the way. Later I will diverge even more to plain C/g++/.. code probably, using some RTOS or so, but now my needs are not so far yet. (google "arduino rtos" I am currently reading https://github.com/greiman/NilRTOS-Arduino )
Arduino is not meant to be "best practice" anyway. It is meant to be "fast and easy way to do something, when you know nothing". And it works, as anybody and his dog can start with Arduino and if interested, he can go more far on his own, or he can stick with easy and have fun anyway.
crosscompiling