Reusability is the essence of development in some way. I mean it is really important and it is a serious issue if you can't make a reusable code in the engine so I understand the frustration. Every experienced programmer always keep in mind to make that feature which he is already working on a kind of universal/reusable code (lib, plugin, module, ...). Reasons are obvious.
As it is not that stright forward to make a reusable code in C2 - still it is possible. My MoModth project which I talk about from time to time is based on (what I call) modules. Depends on the feature a module can be a functionality with dedicated API (both functions and callbacks) or stand alone functionality. This approach really does the job. That's why I say for MoModth that "Building C2 apps has never been easier", because you can simply attach modules which you use in current layout and they handle most of needed functionality.
Think about it like on libraries in regular programming languages. You download a library and use it with it's API. So I really encourage to take this approach while building C2 apps. It saves a lot of time and speed up development drastically. Also once you make a good module it is already tested/working code so you don't have to bother with bugs/compatibility.
I wish MoModth be finished already as this is a close related topic with issue that MoModth's is solving actualy. I am however very bussy recently with my client's projects so MoModth has to wait a bit.
Anyway I assure you that C2 can handle big projects you just have to figure out your own smart coding guideline, some conventions for the project which will let you not get lost once it gets big.
In shot: ENCAPSULATING!, organizing, optimizing and overall refactoring should be done as soon as your project evolves with some new "wing".
Good Luck