...At first I thought that shiftIn() and shiftOut() were the answer, but I don't see how to achieve the bidirectional concurrent transfer with those - is 'bit banging' the only option here, or am I missing a trick?
That's correct, shiftIn()/Out() aren't for bidirectional communication at the bit level. If you can program both communication endpoints you could use shiftin/out to communicate full bytes at a time by alternating calls...it would be slower, but you may not need to send massive amounts of data back and forth so that may not matter. If you only have control over the Arduino side and the other component only speaks hardware SPI, obviously this won't work....
As I was typing this an idea comes to mind -- what about using one of those remap-any-pin shields to swap some lines so your hardware SPI pins are freed up?
 - This is what I'm talking about https://www.sparkfun.com/products/11002?