South Africa made a bright start, with Aiden Markram stroking 31 off 38 balls in an opening stand of 47 with Elgar.
But Markram fell leg before wicket to first innings bowling hero Thakur, who won a verdict from umpire Marais Erasmus after two earlier unsuccessful appeals in the same over.
Run-scoring became increasingly difficult, with uneven bounce becoming more of a factor as the sun beat down on a pitch which has given help to the fast bowlers throughout the match.
But it was off-spinner Ravichandran Ashwin who made the second breakthrough when he trapped Keegan Petersen in front of his stumps for 28 with the total on 93.
After losing the first Test in Centurion, South Africa need to win to keep the series alive ahead of next week's third and final Test in Cape Town. With only six recognised batsmen in their line-up, a tense finish is in prospect for Thursday.
India's second innings total of 266 owed much to Cheteshwar Pujara and Ajinkya Rahane, who put on 111 for the third wicket.
Fast bowler Kagiso Rabada brought South Africa back into the match with a burst of three wickets after Pujara and Rahane added 66 runs in 14 overs to the overnight total of 85 for two with the most fluent batting of the match.
The two veterans, criticised recently after a string of low scores, both went to rapid half-centuries as they took advantage of inconsistent bowling by South Africa on a pitch still offering plenty of help to fast bowlers.
Rabada struck in the first over after the mid-morning drinks break when Rahane was caught behind for 58, scored off 78 balls with eight fours and a six.
In his next over Rabada trapped Pujara leg before wicket for 53. Pujara reached his half-century off 62 balls with 10 fours but only added another three from 24 deliveries before his dismissal.
Rishabh Pant was struck on the shoulder by a Rabada bouncer and then charged at the next ball and edged a catch to wicketkeeper Kyle Verreynne to depart for nought.
Hanuma Vihari made 40 not out and there was aggressive batting from Ravichandran Ashwin (16) and Shardul Thakur (28) as India added 99 runs for the loss of their last five wickets.
Rabada, Lungi Ngidi and Marco Jansen took three wickets apiece.