Alternatively, spending a lot of lead time doing OO analysis in such cases is more like premature optimization. Instead, if the problem does not appear obviously OO, just implement it as procedural/structural, but implement it properly trying to keep the scopes and states as limited as needed. If a better model, perhaps OO, could emerge from such implementation, then it could be applied in the next iteration.
EDIT: typo
But in the end we should be less dogmatic in general . Myself and a lot of people I know started out building big inheritance trees only to find out that this didn’t work so well so we reduced it to a degree that was useful and manageable. But then you have some very loud dogmatists who scream “this is not OOP” and insist on building factories and factories of factories and all the other nonsense. And for some reason the dogmatists often get heard, maybe because they are so loud and convinced of themselves.
If you build a library or framework, you'll use it more. There are often plenty of literal "is-a" relationships that don't exist as often in application code. So you probably benefit from inheritance in OOP quite a bit even if you aren't building those relationships yourself.
If you focus on the compositional relationship you get a lot more mileage out of OOP which is the real revolution over the past 15 years. And the decomposition is how you arrive at the Single Responsibility Principle and Encapsulation. Suddenly you can work only with the set of all Complications, or the Face, or Time or Date without worrying about which Watch you have.
taking in a pointer to a struct as an argument is much less overhead for the programmer than "ok this is an 'object' here is why it is doing what it's doing oh here is this method etc etc"