The tourists were on 68/2 in their second innings, trailing by 98 runs, with Cheteshwar Pujara on 32 and Virat Kohli on 11 at stumps.
Having bowled the Proteas out for 500 in their first innings shortly after tea, India lost Murali Vijay in the sixth over when the opener got an outside edge off paceman Vernon Philander to Graeme Smith in the slips for six runs.
South Africa then took a knock when Hashim Amla attempted a tough chance off Pujara at short leg and he was taken off for medical treatment with a bleeding hand.
The Proteas nonetheless tightened their grip on the match when Faf du Plessis took a magnificent one-handed overhead catch to remove Shikhar Dhawan for 19 runs, with the opener attempting to smash Robin Peterson over midwicket, after the umpires forced the hosts to bowl their spinners due to bad light.
Earlier, Jacques Kallis had every member of a sparse crowd on their feet as he reached his 45th career century in his final Test match.
The veteran all-rounder compiled a typically patient ton as the Proteas took firm control of the deciding match of the two-Test series.
He was at the crease for more than six hours overnight, facing 316 deliveries for his 115 runs, with 13 boundaries.
However, three balls after overhauling retired Indian batsman Rahul Dravid as the third-highest scorer in Test cricket, with 13 289 runs, he got a thick top edge off spin bowler Ravindra Jadeja, with wicketkeeper MS Dhoni taking a sitter.
Three overs later, seamer Zaheer Khan had night watchman Dale Steyn, who shared 86 runs for the sixth wicket with Kallis, caught behind for 44 runs shortly before lunch.
Robin Peterson and Faf du Plessis punished India’s bowlers with a superb cameo partnership in the afternoon session as the hosts drew well clear in their first innings.
The duo shared a quickfire 110-run stand for the eighth wicket.
Peterson smashed 61 runs off 52 balls, with nine fours and a six, but he tried to go big again in an effort to stretch the advantage and he was caught by Murali Vijay after contributing his third career half-century.
With Proteas captain Graeme Smith reluctant to declare after rain brought forward the tea break, the Indian attack needed just seven balls after the interval to dismiss the hosts.
Jadeja, who replaced Ravichandran Ashwin in the Indian side after the drawn first Test at the Wanderers, led the tourists’ attack as he returned a career best 6/138.