PPCG Senior Prank

Retina, 41 bytes

Byte count assumes ISO 8859-1 encoding.

(?<=(.)*)(?=.*¶(?>(?<-1>.)*)\S{3})   
/~\

Note that the first line has three trailing spaces.

Requires the input to be padded to a rectangle.

Try it online!

Explanation

This is fairly standard vertical matching:

(?<=(.)*)

This counts the characters preceding the match by capturing that many characters into group 1.

(?=.*¶(?>(?<-1>.)*)\S{3})

This checks that there are three non-space characters on at the same position in the next line. This is done by popping from group 1 until its empty with (?<-1>.)* and preventing backtracking with the atomic group (?>...).

Finally we match the actual spaces. Those are simply replaced with the literal string /~\. Conveniently, matches are found from left to right and cannot overlap.


JavaScript (ES6), 163 bytes

a=>(z=a.split`
`,z.unshift(z[0].replace(/./g,' ')),z).map((b,i)=>b.replace(/   /g, (c,j)=>(!z[i+1]||!z[i+1][j+2]||/ /.test(z[i+1].slice(j,j+3))?c:'/~\\'))).join`
`

Quickly hacked together solution, can definitely be golfed down. Adds a blank line above, finds triple spaces, and replaces with a cup if the next line does not contain any spaces. Makes the allowed assumption that input will be rectangular. Any backspaces in the input need escaping (as one would expect with JS).