Waters' bases-loaded liner to left highlighted a four-run eighth for the Royals, who have won five of six but remain buried in last place with a 49-102 mark.
The loss snapped a three-game Cleveland (72-79) winning streak, hampering their faint playoff hopes as they chase the Minnesota Twins (79-71) in the American League Central Division.
Trevor Stephan (6-7) hit a batter and walked three, driving in one run, and loading the bases ahead of Waters' double. Waters had two of Kansas City's six hits, snapping his 0-for-12 slump.
Jackson Kowar (2-0) earned the win with a scoreless eighth and James McArthur collected his first career save with a perfect ninth.
Bo Naylor's RBI double highlighted a two-run second inning as Cleveland grabbed a 2-0 lead.
Kansas City got on the scoreboard in the third when Bobby Witt Jr. beat out an infield hit, stole second and scored on MJ Melendez's triple. Witt has nine steals in his past eight games and his 48 stolen bases are the most for the Royals since Tom Goodwin's 66 in 1996.
With one out in the fourth, Gabriel Arias drove Brady Singer's sinker over the right field wall for his 10th home run. Arias added a sacrifice fly in the sixth for a 4-1 lead.
Guardians leadoff hitters reached safely in four of six innings against Singer, who went six innings, allowing four runs on eight hits and two walks.
In the sixth, Nelson Velázquez hammered Guardians starter Cal Quantrill's splitter 425 feet to left, cutting the deficit to 4-2. It was Velázquez's 14th of the season and 11th with Kansas City.
Quantrill pitched 5 2/3 innings, allowing two runs on five hits with three strikeouts.
José Ramírez walked leading off the third and stole second for his 200th career stolen base.
Andrés Giménez collected three of Cleveland's nine hits and stole his 29th base.
—Field Level Media