I feel like it should be supported, since PW itself uses two modules directories, core and site, and they’re not hardcoded. When ProcessWire instantiates itself, it calls addPath() for /site/modules/ here (the core modules path is added in Modules::__construct):
// from ProcessWire::load(Config $config)
$modules = $this->wire('modules', new Modules($config->paths->modules), true);
$modules->addPath($config->paths->siteModules);
$modules->setSubstitutes($config->substituteModules);
$modules->init();
https://github.com/processwire/processwire/blob/3cc76cc886a49313b4bfb9a1a904bd88d11b7cb7/wire/core/ProcessWire.php#L557
The problem is that addPath() needs to be called between the instantiation of Modules and the init() call and there’s no way for us to get in there. Unfortunately there don’t appear to be any hookable methods during this process (I don’t think hooks can be attached before this point anyway?).
But I think you can get away with just adding your path after the fact and calling Modules::refresh():
// seems to work in init.php
wire('modules')->addPath(__DIR__ . '/modules-2/');
wire('modules')->refresh();
Of course this adds a lot of unnecessary cost to every request, because it basically loads all modules again. And I don’t think it’ll work for preload modules.
If this is important to you maybe ask Ryan to make this a config setting? ProcessWire already uses an array for module directories, only the assumption that the first two entries are core/modules and site/modules seems to be baked in.