It isn't ambiguous. Your analysis is correct.
Here's a mechanical check of your grammar (reshaped for our tool):
S = S Sprime ;
S = a ;
S = b ;
Sprime = a ;
Sprime = b ;
Execution of tool:
C:\DMS\Domains\DMSStringGrammar\Tools\ParserGenerator>run ParserGenerator.P0B -interactive C:\
DMS GLR Parser Generator 2.4.1
Copyright (C) 1997-2018 Semantic Designs, Inc.
Opening C:\temp\Example.bnf
*** EOF seen
<<<Rule Collection Completed>>>
NTokens = 5 NRules = 5
LR(1) Parser Generator -- Find Follow and SLR Lookahead sets
Computing MemberSets for Nonterminal Tokens...
What next? ambiguities 100
Print results where (<CR> defaults to console)?
Default paper width: 80
How wide should the printout be (<CR> selects default)?
*** Search for ambiguities to depth 100
Nonterminal < Sprime > is not ambiguous
*** Search for ambiguities to depth 1; trying 2 rule pairs...
*** Search for ambiguities to depth 2; trying 2 rule pairs...
*** Search for ambiguities to depth 3; trying 2 rule pairs...
*** Search for ambiguities to depth 4; trying 2 rule pairs...
Nonterminal < S > is not ambiguous [modulo rule derivation loops]
*** 0 ambiguities found ***
*** All ambiguities in grammar detected ***
This tool is rather overkill for grammar with two nonterminals. But when somebody gives a set of 200 nonterminals it is much harder to do by hand.
(For theorists: this tool obviously can't decide this for all grammars.
It uses a recursive iterative deepening search in the space of nonterminal expansions to look of duplicate/ambiguous expansions. That's works pretty well in pratice).