To use the scons cache you have to have a target. scons caches the target based on the contributing files and build command.
Even without a builder, you can write yourself a Command processor a bit like this.
out_cc = env.Command('file.wave.cpp', 'file.cpp', 'wave command < $SOURCE > $TARGET')
env.Program('myprog', ['this.cc', 'that.cc', out_cc])
This will use the cache.
You can add a builder if you like, so you can do that in all one step. Builders are nice for where you'll use the same command in multiple places or have more complex requirements than can be described with a simple Command. However, they aren't essential for the cache to work.
Edit: Updated to include liosan's solution for wave taking .cpp files and producing .cpp files and hence getting the include dependencies right. Desperate for reputation I am...