Here is my solution :
I create a hidden column in the concerned list to store the next item's version label that will be generated by the flow. I simply compute it by incrementing the current version label and store result in the hidden column on item update. In trigger condition I just check if SystemUpdateVersion matches item version label.
So on the one hand, when flow updates an item, both item version label and SystemUpdateVersion get same value, item version label is incremented by system and SystemUpdateVersion by flow, next trigger's firing attempt will then be ignored due to trigger's condition. On the other hand, when users update item, both values will never match, user can't modify SystemUpdateVersion, system will increment item version label but SystemUpdateVersion won't be incremented and flow will be fired cause trigger's condition is fulfilled.
Here how to build this :
1° Add a single line of text column named "SystemUpdateVersion" to the list and hide it from edit form
2° Create a Flow that uses the SharePoint “When an item is created or modified” trigger
3° Add the following expression as trigger condition in trigger settings :
@not(equals(triggerOutputs()?['body/SystemUpdateVersion'],triggerBody()['{VersionNumber}']))
Tip: if you also want flow to ignore item creation to deal with item modifications only, add the following expression :
@not(equals(triggerBody()['Created'],triggerBody()['Modified']))

4° Add a compose action and set the following inputs :
formatNumber(add(float(triggerOutputs()?['body/{VersionNumber}']), 1), 'F1')
5° Add an Update item action to update item that fired the trigger and set the "SystemUpdateVersion" field value using the previous compose outputs.
Hope this will help !
[Edit 01/18/2024] Trigger condition didn't work anymore, changed triggerBody()['SystemUpdateVersion'] by triggerOutputs()?['body/SystemUpdateVersion'] to fix.